# coding:utf-8
'''
Created on 2010-1-2

@author: Jason Green
@author-email: guileen@gmail.com
'''
from django.http import HttpRequest
from django.core.context_processors import request
from djangosnippets.contrib.bench.models import TimeCost
from django.conf import settings
from django.utils.datetime_safe import datetime
import thread
import time

_bench_queue={}
_ready_queue=[]
class BenchObject:
    def __init__(self,request,method,elapsed_time,*args,**kwargs):
        self.request=request
        self.method=method
        self.elapsed_time = elapsed_time
        self.args=args
        self.kwargs = kwargs
        self.create_time = datetime.now()
        
    def save(self):
        cost = TimeCost()
        cost.elapsed_time = self.elapsed_time
        cost.create_time = self.create_time
        if(self.method):
            while(hasattr(self.method, '_orign_method')):
                self.method = self.method._orign_method
            if(hasattr(self.method, 'im_class')):
                cost.method_name = str(self.method.im_class)+self.method.im_func.__name__
            elif(hasattr(self.method, 'im_func')):
                cost.method_name= self.method.im_func.__name__
            else:
                raise Exception('no method name attribute found')
            cost.args = unicode(self.args)
            cost.kwargs = unicode(self.kwargs)
        if(request):
            cost.request_id = getattr(self.request,"uuid")
            cost.request_method = self.request.method
            cost.request_object = unicode(self.request)
            cost.request_url = self.request.build_absolute_uri()
            cost.is_ajax = self.request.is_ajax()
            user = getattr(self.request,"user")
            cost.user = user and user.username
        cost.save()
        
def log_cost(request,method,elapsed_time,*args,**kwargs):
    if(request==None):
        raise Exception('request cannot be None')
    if(request not in _bench_queue):
        _bench_queue[request]=[]
    _bench_queue[request].append(BenchObject(request,method,elapsed_time,*args,**kwargs))
    
def do_log(request):
    #FIXME: 使用异步方式，将cost pending 保存，否则内存可能不断增长，返回response可能会有延时
    if(request in _bench_queue):
        _ready_queue.append(_bench_queue[request])
        del _bench_queue[request]

def real_log(interval):
    while True:
        while len(_ready_queue)>0:
            for bench in _ready_queue.pop():
                bench.save()
        time.sleep(interval)
thread.start_new_thread(real_log,(5,))
            
def time_interceptor(method,*args,**kwargs):
    if(hasattr(method, 'no_bench')):
        return method(*args,**kwargs)
    start = time.time()
    if(len(args)>0 and isinstance(args[0], HttpRequest)):
        request = args[0]
    else:
        request = None
    res=method(*args,**kwargs)
    elapsed_time = time.time()-start
    if elapsed_time>0.001 :
        log_cost(request,method,elapsed_time,*args,**kwargs)
    return res

class RequestTimeMiddleware(object):
    def process_request(self, request):
        request._start_time = time.time()
        import uuid
        request.uuid = str(uuid.uuid4())

    def process_response(self, request, response):
        elapsed_time = time.time() - request._start_time
        if elapsed_time>0.001:
            log_cost(request,None,elapsed_time)
        do_log(request)
        return response
    
    process_request.no_bench=True
    process_response.no_bench=True